package com.qzyh.esb.egsa.utils;

import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.BCUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.crypto.symmetric.SM4;
import com.qzyh.esb.egsa.bean.bo.Sm2Key;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.math.ec.ECPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.Base64;


public class GmUtil {

    private static final Logger logger = LoggerFactory.getLogger(GmUtil.class);

    /**
     * 字节数组转Base64编码
     *
     * @param bytes 字节数组
     * @return Base64编码
     */
    public static String bytesToBase64(byte[] bytes) {
        byte[] encodedBytes = Base64.getEncoder().encode(bytes);
        return new String(encodedBytes, StandardCharsets.UTF_8);
    }

    /**
     * Base64编码转字节数组
     *
     * @param base64Str Base64编码字符串
     * @return bytes 字节数组
     */
    public static byte[] base64ToBytes(String base64Str) {
        return Base64.getDecoder().decode(base64Str);
    }

    /**
     * 生成SM2密钥
     *
     * @return Sm2Key
     */
    public static Sm2Key genSm2Key() {
        logger.info("生成SM2密钥开始");
        //生成一对公私钥
        SM2 sm2 = SmUtil.sm2();
        BCECPrivateKey privateKey = (BCECPrivateKey) (sm2.getPrivateKey());
        //私钥对应D值，EC为椭圆算法
        BigInteger d = privateKey.getD();
        BCECPublicKey publicKey = (BCECPublicKey) sm2.getPublicKey();
        //公钥对应Q值
        ECPoint q = publicKey.getQ();
        String privateKeyStr = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(privateKey));
        String publicKeyStr = HexUtil.encodeHexStr(q.getEncoded(false));
        logger.info("生成SM2密钥结束");
        return new Sm2Key(publicKeyStr, privateKeyStr);
    }

    /**
     * SM2解密
     *
     * @param sm2Key SM2密钥
     * @param cipherText 密文
     *
     * @return Sm2Key
     */
    public static String sm2Decrypt(Sm2Key sm2Key, String cipherText) {
        SM2 sm2 = SmUtil.sm2(sm2Key.getPrivateKey(),sm2Key.getPublicKey());
        return  new String(sm2.decrypt("04"+cipherText, KeyType.PrivateKey));
    }

    /**
     * SM4加密
     *
     * @param sm4Base64Str SM4密钥base64编码字符串
     * @param text 明文
     *
     * @return cipherText base64编码密文字符串
     */
    public static String sm4Encrypt(String sm4Base64Str, String text) {
        SM4 sm4 = SmUtil.sm4(GmUtil.base64ToBytes(sm4Base64Str));
        byte[] cipherText = sm4.encrypt(text.getBytes());
        return GmUtil.bytesToBase64(cipherText);
    }


    public static void main(String[] args) {
//        String txtStr = "2324kkjasdoo000**&";
//        SM2 sm2 = SmUtil.sm2();
//        PrivateKey privateKey = sm2.getPrivateKey();
//        PublicKey publicKey = sm2.getPublicKey();
//        String privateKeyStr = GmUtil.bytesToBase64(privateKey.getEncoded());
//        String publicKeyStr = GmUtil.bytesToBase64(publicKey.getEncoded());
//        String cipherText = sm2.encryptBase64(txtStr.getBytes(), KeyType.PublicKey);
//        System.out.println("cipherText:" + cipherText);
//        byte[] decryptText = sm2.decrypt(cipherText,KeyType.PrivateKey);
//        System.out.println("decryptText:" + new String(decryptText));

//        String privateKeyStr = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg6s14A0dJJd4Y+ahJniakIL0a4FlgnkS37hGZePwUDHigCgYIKoEcz1UBgi2hRANCAATl2JXvygU7hWfw2jMnu+1h13aSO2z9UnTyGxhEn0SEGrnD3wIkklA92I1Pe+0I2kYdarnDHcN2B//azGedFjgG";
//        String publicKeyStr = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE5diV78oFO4Vn8NozJ7vtYdd2kjts/VJ08hsYRJ9EhBq5w98CJJJQPdiNT3vtCNpGHWq5wx3Ddgf/2sxnnRY4Bg==";
//        System.out.println("privateKey:" + privateKeyStr);
//        System.out.println("publicKey:" + publicKeyStr);
//        SM2 sm2 = SmUtil.sm2(privateKeyStr,publicKeyStr);
//        String cipherText2 = sm2.encryptBase64(txtStr.getBytes(), KeyType.PublicKey);
//        String cipherText2 = "04fHBOGFysTbM4Pay5EnTwKeSriyh6/eFmgPr1PQ9UelkQVjdtaXtya0umSqDElR8SQyV6XeXjDBGRKhrWsysHRiS/3/knkeWzOeFECp5bFjGHHVPt/9QTXo4IQWzDHj34yonkiYE=";
//        byte[] decryptText2 = sm2.decrypt(cipherText2,KeyType.PrivateKey);
//        System.out.println("decryptText3:" + new String(decryptText2));

        //sm4key:nUq/DjkzaXTw9voV6XTQ6Q==
        //cipherText:pk2pvVn6QUnwwJ2VPlJK60Cpthit9o+pCa0vqf3Z8H4=
//        SM4 sm4 = SmUtil.sm4();
//        SecretKey sk = sm4.getSecretKey();
//        System.out.println(GmUtil.bytesToBase64(sk.getEncoded()));
//        byte[] cipherText = sm4.encrypt(txtStr.getBytes());
//        System.out.println("cipherText:" + GmUtil.bytesToBase64(cipherText));
        SM4 sm4 = SmUtil.sm4(GmUtil.base64ToBytes("nUq/DjkzaXTw9voV6XTQ6Q=="));
        String txtStr = "123456";
        byte[] cipherText = sm4.encrypt(txtStr.getBytes());
        System.out.println("cipherText:" + GmUtil.bytesToBase64(cipherText));
//        String cipherText = "pk2pvVn6QUnwwJ2VPlJK60Cpthit9o+pCa0vqf3Z8H4=";
//        byte[] decryptText = sm4.decrypt(GmUtil.base64ToBytes(cipherText));
//        System.out.println("decryptText3:" + new String(decryptText));


    }
}
